package com.jari.lg.utils;

import com.alibaba.fastjson.JSON;
import com.jari.lg.domain.CrossBase;
import com.jari.lg.domain.KeyArea;
import io.swagger.models.auth.In;
import org.javatuples.Pair;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.logging.SimpleFormatter;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;
import java.util.UUID;

public class Utils {


    public static String[] cityAbbrs = {"京", "沪", "津", "渝", "黑", "吉", "辽", "冀", "甘", "青", "陕", "豫", "鲁",
            "晋", "皖", "鄂", "湘", "苏", "川", "黔", "滇", "桂", "浙", "赣", "粤", "闽", "琼", "港", "澳", "内", "新", "宁", "藏"};
    public static String[] provinceLetter = {"A", "B", "C", "D"};
    public static String[] numberLetter = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
    public static String[] plateLetter = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C",
            "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "X", "Y", "Z"};

    public static final int PLATENUMBERQUEUESIZE = 10;
    public static Queue<String> plateNumberQueue = new ArrayBlockingQueue<>(PLATENUMBERQUEUESIZE);

    public static SimpleDateFormat hourFormatterWithoutSep = new SimpleDateFormat("yyyyMMddHH");
    public static SimpleDateFormat normalformatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static final Integer SECONDS_IN_HOUR = 3600;
    public static final Integer MILLISECONDS_IN_SECOND = 1000;
    public static final Integer MINUTES_IN_HOUR = 60;
    public static final Integer HOURS_IN_DAY = 24;


    /*
    *  保存一天过车的数据信息
    * */
    public static Map<String, Integer> CAR_NUM = new HashMap<>();


    /*
    * 构造车辆日统计的本地与非本地数值
    * */
   static  {
       Utils.CAR_NUM.put(Constants.LOCAL,Utils.makeRandInt(50000) + 50000);
       Utils.CAR_NUM.put(Constants.NO_LOCAL,Utils.makeRandInt(10000)+ 10000);
    }

    /**
     * 产生车牌号
     * 90%为上海车牌
     * 50%为新能源车牌
     *
     * @return
     */
    public static String createPlateNumber() {
        StringBuffer plateNumStr = new StringBuffer();
        Integer rand1 = new Random().nextInt(2);
        if(rand1 == 0 && plateNumberQueue.size() > 0){
            plateNumStr.append(plateNumberQueue.element());
        }
        else{
            String city = cityAbbrs[(new Random().nextInt(cityAbbrs.length))];
            //随机是否外省
            Integer rand = new Random().nextInt(100);
            if (rand >= 10) {
                city = "沪";
            }
            plateNumStr = new StringBuffer(city);
            plateNumStr.append(provinceLetter[new Random().nextInt(provinceLetter.length)]);
            rand = new Random().nextInt(10);
            //是否新能源
            if (rand <= 2) {
                plateNumStr.append(numberLetter[new Random().nextInt(numberLetter.length)])
                        .append(numberLetter[new Random().nextInt(numberLetter.length)])
                        .append(plateLetter[new Random().nextInt(plateLetter.length)])
                        .append(numberLetter[new Random().nextInt(numberLetter.length)])
                        .append(plateLetter[new Random().nextInt(plateLetter.length)])
                        .append(numberLetter[new Random().nextInt(numberLetter.length)]);
            } else {
                plateNumStr.append(numberLetter[new Random().nextInt(numberLetter.length)])
                        .append(plateLetter[new Random().nextInt(plateLetter.length)])
                        .append(numberLetter[new Random().nextInt(numberLetter.length)])
                        .append(plateLetter[new Random().nextInt(plateLetter.length)])
                        .append(numberLetter[new Random().nextInt(numberLetter.length)]);
            }
            while (plateNumberQueue.size() >= PLATENUMBERQUEUESIZE ){
                plateNumberQueue.remove();
            }
            plateNumberQueue.add(plateNumStr.toString());
        }
        return plateNumStr.toString();
    }

    /**
     * 返回车牌类型
     *
     * @return
     */
    public static String createPlateType() {
        Integer rand = new Random().nextInt(10000);
        //红牌
        if (rand == 0) {
            return BaseData.carPlateTypeList.stream().filter(x -> x.getDictlabel().equals(BaseData.carPlateType[2])).findFirst().get().getDictlabel();
        }
        //黄牌
        else if (rand < 50) {
            return BaseData.carPlateTypeList.stream().filter(x -> x.getDictlabel().equals(BaseData.carPlateType[1])).findFirst().get().getDictlabel();
        }
        //蓝牌
        else {
            return BaseData.carPlateTypeList.stream().filter(x -> x.getDictlabel().equals(BaseData.carPlateType[0])).findFirst().get().getDictlabel();
        }
    }

    /**
     * 返回车辆类型
     *
     * @return
     */
    public static String createCarType() {
        Integer rand = new Random().nextInt(10000);
        //特殊车辆
        if (rand < 10) {
            return BaseData.carTypeList.stream().filter(x -> x.getDictlabel().equals(BaseData.carType[1])).findFirst().get().getDictdata();
        }
        //营运车辆
        else if (rand < 1000) {
            return BaseData.carTypeList.stream().filter(x -> x.getDictlabel().equals(BaseData.carType[0])).findFirst().get().getDictdata();
        }
        //私家车
        else {
            return BaseData.carTypeList.stream().filter(x -> x.getDictlabel().equals(BaseData.carType[2])).findFirst().get().getDictdata();
        }
    }

    /**
     * 返回违法类型
     *
     * @return
     */
    public static String createViolationType() {
        Integer rand = new Random().nextInt(BaseData.violationType.length);
        return BaseData.violationType[rand];
    }

    /**
     * 返回交叉口
     *
     * @return
     */
    public static CrossBase createJnc() {
        Integer rand = new Random().nextInt(BaseData.crossBaseList.size());
        return BaseData.crossBaseList.get(rand);
    }

    /**
     * 返回交叉口
     *
     * @return
     */
    public static CrossBase createJncByJncCode(String jncCode) {
        return BaseData.crossBaseList.stream().filter(x -> x.getCrosscode().equals(jncCode)).findFirst().orElse(null);
    }

    /**
     * 返回0-bound(不包括)的小数
     * @param bound
     * @return
     */
    public static Double createPriceWithBound(Integer bound){
        return new Random().nextDouble() * bound;
    }


    /**
     * 获取交叉口的重点区域，可能为null
     *
     * @return
     */
    public static KeyArea getKeyareaById(String keyAreaId) {
        return BaseData.keyAreaList.stream().filter(x -> x.getId().equals(keyAreaId)).findFirst().orElse(null);
    }

    /**
     * 获取UUID
     *
     * @return
     */
    public static String getUUID() {
        return UUID.randomUUID().toString();
    }


    /**
     * 获取时段的开始和结束时间
     * @param date 基础天
     * @param periodId 0-23
     * @return
     */
    public static Pair<Date, Date> getPeriodDateByPeriodId(Date date, Integer periodId) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        Date startDate = new Date(cal.getTime().getTime() + periodId * 3600 * 1000);
        cal.setTime(startDate);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        Date endDate = cal.getTime();
        return new Pair<>(startDate, endDate);
    }

    /**
     * 获取两个日期相差小时数
     * @param date1
     * @param date2
     * @return
     */
    public static Long getHoursBetweenDates(Date date1, Date date2){
        return (date1.getTime() - date2.getTime()) / SECONDS_IN_HOUR / MILLISECONDS_IN_SECOND;
    }

    /**
     *
     *
     * 生成随机数
     * @return
     */
    public static int makeRandInt(int bonder){
        Random random = new Random();
        return random.nextInt(bonder);
    }

    /**
     *
     *
     * 传入时间的随机数后的时间
     * @return
     */
    public static Date makeAfterDate(int minites){
        long currentTime = System.currentTimeMillis() + minites * 60 * 1000;
        Date date = new Date(currentTime);
        return date;

    }

    /**
     *
     *
     * 随机产生车辆颜色
     * @return
     */
    public static String makeColor(){
        String[] clolors = {"黑色","白色","黄色","红色","蓝色","橙色","青色"};
        Random random = new Random(clolors.length);
        return clolors[random.nextInt()];
    }

    /**
     *
     *
     * 产生事件名
     * @return
     */
    public static String makeEventName(){
        String[] names = {"发生交通事故","行人闯红灯","路口拥堵","关闭闸口","特勤执行","发生打架斗殴"};
        Random random = new Random(names.length);
        return names[random.nextInt()];
    }

    /**
     *
     *
     * 产生事件类型
     * @return
     */
    public static String makeEventType(){
        String[] types = {"1","2","3","4","5","6"};
        Random random = new Random(types.length);
        return types[random.nextInt()];
    }

    /**
     *
     *
     * 产生随机数双精度
     * @return
     */
    public static double makeDouble(int range){
        Random random = new Random();
        //产生一个[0,range]的double数值
        double num = Double.valueOf(Math.floor(random.nextDouble()*range));
        return num;
    }

    /**
     *
     *
     * 产生随机数长整型
     * @return
     */
    public static long makeLong(int range){
        Random random = new Random();
        long num = Long.valueOf(random.nextLong()* range);
        return num;
    }


    public static String makeRandProvince(int size){
        Set<String> provinceSet = new HashSet<>();
        if(size < 1){
            return null;
        }
        for(int i = 0 ; i < size ; i ++){
            provinceSet.add(cityAbbrs[makeRandInt(cityAbbrs.length)]);
        }

        return JSON.toJSONString(provinceSet);
    }

    /*
    *  构造设备故障成因的风向
    * */
    public static String makeWindDirection(){
        String[] directions = {"北","东北","东","东南","南","西南","西","西北"};
        return directions[makeRandInt(8)];
    }

    /*
    * 天气
    * */
    public static String makeWeather(){
        String[] weathers = {"晴","阴天","小雨","中雨","大雨","多云","雾天","晴转多云","小雪","中雪","大雪"};
        return weathers[makeRandInt(weathers.length)];
    }

    /*
    * 返回风的等级
    * */
    public static String windLevel(){
        String[] levels = {"<3","<4","<5","<6","<7","<8","<9","<10"};
        return levels[makeRandInt(levels.length)];
    }

    public static void main(String[] args) {
        while (true){
            System.out.println(createPlateNumber());
        }
    }

}
